package com.leyou.item.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.enums.LyExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.utils.constants.MQConstants;
import com.leyou.common.vo.PageResult;
import com.leyou.item.dto.*;
import com.leyou.item.mapper.CategoryMapper;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.pojo.Sku;
import com.leyou.item.pojo.Spu;
import com.leyou.item.pojo.SpuDetail;
import com.leyou.item.service.BrandService;
import com.leyou.item.service.CategoryService;
import com.leyou.item.service.GoodsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private SpuDetailMapper spuDetailMapper;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private SkuMapper skuMapper;

//分页查询spu
    @Override
    public PageResult<SpuDTO> querySpuByPage(Integer page, Integer rows, Boolean saleable, String key) {
        PageHelper.startPage(page,rows);
        Example example = new Example(Spu.class);
        if (StringUtils.isNotBlank(key)){
example.createCriteria().andLike("name", "%" + key + "%");
        }
        if (saleable!=null){
            example.createCriteria().andEqualTo("saleable", saleable);
        }
        List<Spu> spuList = spuMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(spuList)){
            throw new LyException(LyExceptionEnum.GOODS_NOT_FOUND);
        }

        List<SpuDTO> spuDTOList = BeanHelper.copyWithCollection(spuList, SpuDTO.class);

        handleCategoryAndBrandName(spuDTOList);
        PageInfo pageInfo = new PageInfo(spuList);


        return new PageResult<SpuDTO>(pageInfo.getTotal(),spuDTOList);
    }

//用来处理数据库与页面之间的转换,由id转为name
    private void handleCategoryAndBrandName(List<SpuDTO> list) {
        for (SpuDTO spu : list) {
            // 查询分类,采用流失编程
            String categoryName = categoryService.queryCategoryByIds(spu.getCategoryIds())
                    .stream()
                    .map(CategoryDTO::getName).collect(Collectors.joining("/"));
            spu.setCategoryName(categoryName);
            // 查询品牌
            BrandDTO brand = brandService.queryById(spu.getBrandId());
            spu.setBrandName(brand.getName());
        }
    }

    @Override
    public void saveGoods(SpuDTO spuDTO) {
        // 从dto中取出spu信息
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        // 保存spu
        spu.setId(null);
        spu.setCreateTime(null);
        spu.setSaleable(false);
        int count = spuMapper.insertSelective(spu);
        if (count != 1) {
            throw new LyException(LyExceptionEnum.INSERT_OPERATION_FAIL);
        }

        // 初始化SpuDetail信息
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        SpuDetail spuDetail = BeanHelper.copyProperties(spuDetailDTO, SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        // 保存spu详情
        count = spuDetailMapper.insertSelective(spuDetail);
        if (count != 1) {
            throw new LyException(LyExceptionEnum.INSERT_OPERATION_FAIL);
        }

        List<SkuDTO> skuDTOList = spuDTO.getSkus();
        List<Sku> skuList = new ArrayList<>();
        for (SkuDTO skuDTO : skuDTOList) {
            skuDTO.setSpuId(spu.getId());
            skuDTO.setEnable(false);
            skuList.add(BeanHelper.copyProperties(skuDTO, Sku.class));
        }
        // 保存sku
        count = skuMapper.insertList(skuList);
        if (count != skuList.size()) {
            throw new LyException(LyExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    @Autowired
    private AmqpTemplate amqpTemplate;//使用AmqpTemplate来发送消息
//上下架操作,修改spu和sku中的可用状态
    @Override
    public void updateSpuSaleable(Long id, Boolean saleable) {
        Spu spu = new Spu();
        spu.setId(id);
       spu.setSaleable(saleable);
        int count = spuMapper.updateByPrimaryKeySelective(spu);
        if (count!=1){
            throw new LyException(LyExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        // 2.更新sku
        // 2.1.准备要更新的数据
        Sku sku = new Sku();
        sku.setEnable(saleable);
        // 2.2.准备更新的匹配条件
        Example example = new Example(Sku.class);
        example.createCriteria().andEqualTo("spuId", id);
        count = skuMapper.updateByExampleSelective(sku, example);

        int size = skuMapper.selectCountByExample(example);
        if (count != size) {
            throw new LyException(LyExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        //商品上下架，同步操作索引库和静态页服务     rabbitmq 生产者代码
        //MQConstants定义的常量类,里面定义了交换机,队列信息,以及携带的routing_key
        String routingKey=saleable ? MQConstants.RoutingKey.ITEM_UP_KEY : MQConstants.RoutingKey.ITEM_DOWN_KEY;

        amqpTemplate.convertAndSend(MQConstants.Exchange.ITEM_EXCHANGE_NAME,routingKey,id);


    }
    //根据spu的id查询spuDetail 数据回显
    @Override
    public SpuDetailDTO querySpuDetailById(Long id) {
        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(id);
        if (spuDetail==null){
            throw new LyException(LyExceptionEnum.GOODS_NOT_FOUND);
        }

        return BeanHelper.copyProperties(spuDetail,SpuDetailDTO.class);
    }
//根据spu的id查询sku   数据回显
    @Override
    public List<SkuDTO> querySkuBySpuId(Long id) {

        Sku sku = new Sku();
        sku.setSpuId(id);
        List<Sku> skuList = skuMapper.select(sku);
        if (CollectionUtils.isEmpty(skuList)) {
            throw new LyException(LyExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(skuList, SkuDTO.class);
    }
//修改商品
    @Override
    public void updateGoods(SpuDTO spuDTO) {
        Long spuId = spuDTO.getId();
        if (spuId == null) {
            // 请求参数有误
            throw new LyException(LyExceptionEnum.INVALID_PARAM_ERROR);
        }
        // 1.删除sku
        Sku sku = new Sku();
        sku.setSpuId(spuId);
        // 查询数量
        int size = skuMapper.selectCount(sku);
        if(size > 0) {
            // 删除
            int count = skuMapper.delete(sku);
            if(count != size){
                throw new LyException(LyExceptionEnum.UPDATE_OPERATION_FAIL);
            }
        }
        // 2.更新spu
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        spu.setSaleable(false);
        spu.setCreateTime(null);
        spu.setUpdateTime(null);
        int count = spuMapper.updateByPrimaryKeySelective(spu);
        if (count != 1) {
            throw new LyException(LyExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        // 3.更新spuDetail
        SpuDetail spuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), SpuDetail.class);
        spuDetail.setSpuId(spuId);
        spuDetail.setCreateTime(null);
        spuDetail.setUpdateTime(null);
        count = spuDetailMapper.updateByPrimaryKeySelective(spuDetail);
        if (count != 1) {
            throw new LyException(LyExceptionEnum.UPDATE_OPERATION_FAIL);
        }

//添加修改后的sku
        List<SkuDTO> skuDTOList = spuDTO.getSkus();
        List<Sku> skus = new ArrayList<>();
        for (SkuDTO skuDTO : skuDTOList) {
            Sku sku1 = BeanHelper.copyProperties(skuDTO, Sku.class);
            sku1.setSpuId(spuDTO.getId());
            sku1.setEnable(false);
            skus.add(sku1);
        }
        int count2 = skuMapper.insertList(skus);
        if (count2!=skus.size()){
            throw new LyException(LyExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }
//用来查询封装商品详情页
    @Override
    public SpuDTO querySpuBySpuId(Long id) {
        Spu spu = spuMapper.selectByPrimaryKey(id);
        SpuDTO spuDTO = BeanHelper.copyProperties(spu, SpuDTO.class);

        spuDTO.setSpuDetail(querySpuDetailById(id));

        spuDTO.setSkus(querySkuBySpuId(id));
        return spuDTO;
    }

}
